package com.remenote.remenoteback.service.impl;


import com.remenote.remenoteback.dao.NoteRepository;
import com.remenote.remenoteback.dao.NotebookRepository;
import com.remenote.remenoteback.dao.UserRepository;
import com.remenote.remenoteback.entity.doo.NoteDo;
import com.remenote.remenoteback.entity.doo.NotebookDo;
import com.remenote.remenoteback.entity.doo.UserDo;
import com.remenote.remenoteback.entity.req.NoteRequest;
import com.remenote.remenoteback.entity.resp.ServerResponse;
import com.remenote.remenoteback.entity.vo.NoteVo;
import com.remenote.remenoteback.entity.vo.NotebookListVo;
import com.remenote.remenoteback.entity.vo.NotebookVo;
import com.remenote.remenoteback.service.NoteService;
import com.remenote.remenoteback.util.ThreadLocalUtil;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
class NoteServiceImpl implements NoteService {
    @Autowired
    private NoteRepository noteRepository;
    @Autowired
    private NotebookRepository notebookRepository;
    @Autowired
    private UserRepository userRepository;

    @Override
    public ServerResponse<List<NoteVo>> allNotes() {
        List<NoteDo> noteDos = noteRepository.findNoteDoByUsernameAndIsDelete(ThreadLocalUtil.getUserName(), false);
        return ServerResponse.buildSuccessResponse(NoteVo.fromNoteDoList(noteDos));
    }

    @Override
    public ServerResponse<NotebookListVo> listNotebooks() {
        List<NotebookDo> notebookDoList = notebookRepository.findNotebookDoByUsernameAndIsDelete(ThreadLocalUtil.getUserName(), false);
        NotebookListVo notebookListVo = new NotebookListVo().setNotebookList(NotebookVo.fromNotebookDoList(notebookDoList));
        return ServerResponse.buildSuccessResponse(notebookListVo);
    }

    @Override
    @Transactional
    public ServerResponse<List<NoteVo>> listNotes(Integer notebookId) {
        NotebookDo notebookDo = notebookRepository.findById(notebookId).orElseThrow();

        List<NoteDo> noteDos = noteRepository
                .findNoteDosByNotebookIdAndUsernameAndIsDelete(
                        notebookDo.getId(),
                        ThreadLocalUtil.getUserName(),
                        false
                );
        List<NoteVo> noteVos = NoteVo.fromNoteDoList(noteDos);
        return ServerResponse.buildSuccessResponse(noteVos);
    }

    @Override
    @Transactional
    public ServerResponse<NoteVo> getNote(String notebookName, String noteTitle) {
        NoteDo noteDo = noteRepository.findNoteDoByNotebookAndNoteTitleAndUsernameAndIsDelete(notebookName, noteTitle, ThreadLocalUtil.getUserName(), false);
        UserDo userDo = userRepository.findByUsername(noteDo.getUsername());
        return ServerResponse.buildSuccessResponse(NoteVo.fromNoteDo(noteDo));
    }

//    @Override
//    public ServerResponse<NoteVo> getNote(Integer id) {
//        return ServerResponse.buildSuccessResponse(NoteVo.fromNoteDo(noteRepository.findById(id).orElseThrow(() ->
//                new RuntimeException("用户不存在"))));
//    }

    @Override
    public ServerResponse<List<NoteVo>> search(String keyWord) {
        List<NoteDo> noteDos = noteRepository.findNoteDoByNoteTitleContainingAndUsernameAndIsDelete(keyWord, ThreadLocalUtil.getUserName(), false);
        return ServerResponse.buildSuccessResponse(NoteVo.fromNoteDoList(noteDos));
    }

    @Override
    @Transactional
    public ServerResponse<NotebookListVo> createNotebook(String notebookName, String description) {
        NotebookDo notebookDo = new NotebookDo()
                .setNotebook(notebookName)
                .setDescription(description)
                .setUsername(ThreadLocalUtil.getUserName());
        notebookRepository.save(notebookDo);
        return listNotebooks();
    }

    @Override
    @Transactional
    public ServerResponse<NoteVo> createNote(String noteTitle, Integer notebookId, String content) {

        NotebookDo notebookDo = notebookRepository.findById(notebookId).orElseThrow();
        NoteDo noteDo = new NoteDo();
        noteDo.setNotebook(notebookDo.getNotebook());
        noteDo.setNotebookId(notebookDo.getId());
        noteDo.setNoteTitle(noteTitle);
        noteDo.setUsername(ThreadLocalUtil.getUserName());
        NoteDo note = noteRepository.save(noteDo);
        return ServerResponse.buildSuccessResponse(NoteVo.fromNoteDo(note));
    }

    @Override
    @Transactional
    public ServerResponse saveNote(NoteRequest noteRequest) {
        NoteDo noteDo = noteRepository.findNoteDoByNotebookAndNoteTitleAndUsernameAndIsDelete(noteRequest.getNotebookName(), noteRequest.getNoteTitle(), ThreadLocalUtil.getUserName(), false);
        noteDo.setNoteContent(noteRequest.getContent())
                .setIsPublic(noteRequest.getIsPublic());
        noteRepository.save(noteDo);
        return ServerResponse.buildSuccessResponse();
    }
    @Override
    @Transactional
    public ServerResponse moveNote(NoteRequest noteRequest) {
        NoteDo noteDo = noteRepository.findById(noteRequest.getDelNoteId()).orElseThrow();
        NotebookDo notebookDo=notebookRepository.findById(noteRequest.getNotebookId()).orElseThrow();
        noteDo.setNotebookId(noteRequest.getNotebookId())
                .setNotebook(notebookDo.getNotebook());
        noteRepository.save(noteDo);
        return ServerResponse.buildSuccessResponse();
    }
        @Override
    @Transactional
    public ServerResponse deleteNote(Integer noteId) {
        NoteDo noteDo = noteRepository.findById(noteId).orElseThrow();
        noteDo.setIsDelete(true);
        noteRepository.save(noteDo);
        return ServerResponse.buildSuccessResponse();
    }

    @Override
    @Transactional
    public ServerResponse deleteNotebook(Integer notebookId) {
        List<NoteDo> noteDos = noteRepository.findNoteDosByNotebookIdAndUsernameAndIsDelete(notebookId, ThreadLocalUtil.getUserName(), false);
        for (NoteDo noteDo : noteDos) {
            noteDo.setIsDelete(true);
            noteRepository.save(noteDo);
        }
        NotebookDo notebookDo = notebookRepository.findById( notebookId).orElseThrow();
        notebookDo.setIsDelete(true);
        notebookRepository.save(notebookDo);
        return ServerResponse.buildSuccessResponse();
    }
}